package cn.piesat.scanning.business.common.algorithm.dataPartition;

import cn.piesat.scanning.business.common.AlgorithmDefineAbstract;
import cn.piesat.scanning.dto.*;
import cn.piesat.scanning.service.*;
import cn.piesat.scanning.utils.FileUtil;
import com.alibaba.fastjson.JSON;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @author xhl
 */
@Component
public class DataPartition extends AlgorithmDefineAbstract {

    @Autowired
    private HtPathConfigurationService htPathConfigurationService;
    @Autowired
    private HtScanningMetadataService htScanningMetadataService;
    @Autowired
    private DbDmsAlgorithmResultStoreService dbDmsAlgorithmResultStoreService;
    @Autowired
    private DbDmsSchedulerTaskFileRecordService dbDmsSchedulerTaskFileRecordService;
    @Autowired
    private DbDmsDatafileNearlineStorageService dbDmsDatafileNearlineStorageService;
    @Autowired
    private HtScheduleJobService htScheduleJobService;

    private static final Logger logger = LoggerFactory.getLogger(DataPartition.class);

    /**
     * 近线状态
     */
    private static final String DATA_STATUS_NEARLINE = "NearLine";

    /**
     * 离线状态
     */
    private static final String DATA_STATUS_OFFLINE = "Offline";

    @Override
    public void exec(Map<String, Object> algorithmParams, String taskId) {
        DataPartitionParams params = JSON.parseObject(JSON.toJSONString(algorithmParams), DataPartitionParams.class);
        Integer day = params.getDay();
        //输入的数据等级形如：L1,L2，根据","将其分割，因涉及两张表，所以需要等级分组后分别进行查询数据
        String inputLevel = params.getDataLevel();
        String[] levels = inputLevel.split(",");
        if (levels.length == 0) {
            logger.info("[数据分区]未输入数据等级，无法分区归档");
            return ;
        }
        HtScheduleJobDTO taskDTO = htScheduleJobService.findById(taskId);
        String dataStatus = params.getDataStatus();
        if (DATA_STATUS_NEARLINE.equals(dataStatus)) {
            nearlinePartition(taskDTO, day, levels);
        } else if (DATA_STATUS_OFFLINE.equals(dataStatus)) {
            offlinePartition(taskDTO, day, levels);
        } else {
            logger.info("[数据分区]数据状态输入不正确，无法分区归档");
        }
    }

    private void offlinePartition(HtScheduleJobDTO taskDTO, Integer day, String[] levels) {
        List<String> levelList = Arrays.asList(levels);
        //查询day天前的近线数据
        List<DbDmsDatafileNearlineStorageDTO> beforeDayData = dbDmsDatafileNearlineStorageService.findBeforeDayAndLevelListData(day,levelList);
        //查询day天内的近线数据
        List<DbDmsDatafileNearlineStorageDTO> afterDayData = dbDmsDatafileNearlineStorageService.findAfterDayAndLevelListData(day,levelList);
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        //查询路径信息
        HtPathConfigurationDTO pathDTO = htPathConfigurationService.findById(taskDTO.getPathConfigId());
        if (!beforeDayData.isEmpty()) {
            logger.info("[数据分区-离线]{}天前的数据共{}个",day,beforeDayData.size());
            //查找原近线数据路径信息
            List<String> pathIdList = beforeDayData.stream()
                    .map(DbDmsDatafileNearlineStorageDTO::getPathConfigId).distinct().collect(Collectors.toList());
            Map<String, HtPathConfigurationDTO> pathHash = htPathConfigurationService.findByIdList(pathIdList)
                    .stream().collect(Collectors.toMap(HtPathConfigurationDTO::getId, dto -> dto, (k1, k2) -> k2));
            for (DbDmsDatafileNearlineStorageDTO dto : beforeDayData) {
                //剪切、修改状态
                HtPathConfigurationDTO srcPathDTO = pathHash.get(dto.getPathConfigId());
                File srcFile = new File(srcPathDTO.getOutputPath() + File.separator + dto.getFilePath());
                File destFile = new File(pathDTO.getOutputPath() + File.separator + dto.getFilePath());
                if (srcFile.exists()) {
                    if (destFile.exists()) {
                        boolean delete = srcFile.delete();
                        if (delete) {
                            logger.info("[数据分区-离线]{}文件删除成功");
                        } else {
                            logger.info("[数据分区-离线]{}文件删除失败");
                        }
                    } else {
                        try {
                            //FileUtils.moveFileToDirectory(srcFile,destFile.getParentFile(),true);
                            FileUtil.moveFileToDirectorySupportsSendfile(srcFile, destFile.getParentFile());
                        } catch (IOException e) {
                            logger.error("[数据分区-离线]{}文件剪切异常：{}",srcFile.getAbsolutePath(),e.getMessage());
                        }
                    }
                }
                dto.setDataStatus(1);
                //该方法是save,但是存在ID，所以是修改
                dbDmsDatafileNearlineStorageService.addEntity(dto);
            }
        }
        if (!afterDayData.isEmpty()) {
            logger.info("[数据分区-离线]{}天内的数据共{}个",day,afterDayData.size());
            //查找原近线数据路径信息
            List<String> pathIdList = beforeDayData.stream()
                    .map(DbDmsDatafileNearlineStorageDTO::getPathConfigId).distinct().collect(Collectors.toList());
            Map<String, HtPathConfigurationDTO> pathHash = htPathConfigurationService.findByIdList(pathIdList)
                    .stream().collect(Collectors.toMap(HtPathConfigurationDTO::getId, dto -> dto, (k1, k2) -> k2));
            for (DbDmsDatafileNearlineStorageDTO dto : afterDayData) {
                //拷贝
                HtPathConfigurationDTO srcPathDTO = pathHash.get(dto.getPathConfigId());
                File srcFile = new File(srcPathDTO.getOutputPath() + File.separator + dto.getFilePath());
                File destFile = new File(pathDTO.getOutputPath() + File.separator + dto.getFilePath());
                if (srcFile.exists() && !destFile.exists()) {
                    try {
                        //FileUtils.copyFile(srcFile,destFile);
                        FileUtil.copyFileSupportsSendfile(srcFile, destFile);
                    } catch (IOException e) {
                        logger.error("[数据分区-离线]{}文件复制异常:{}",srcFile.getAbsolutePath(),e.getMessage());
                    }
                }
            }
        }
        threadPool.shutdown();
    }

    /**
     * 近线分区实现
     * @param taskDTO 任务对象
     * @param day 保留天数
     * @param levels 数据等级
     */
    private void nearlinePartition(HtScheduleJobDTO taskDTO, Integer day, String[] levels) {
        //区分出不同表的数据等级参数
        List<String> metadataLevelList = Arrays.stream(levels)
                .filter(level -> level.toUpperCase().startsWith(DataLevelPrefixEnum.L0.getLevel())
                        || level.toUpperCase().startsWith(DataLevelPrefixEnum.L1.getLevel())
                        || level.toUpperCase().startsWith(DataLevelPrefixEnum.L2.getLevel()))
                .collect(Collectors.toList());
        List<String> resultDataLevelList = Arrays.stream(levels)
                .filter(level -> level.toUpperCase().startsWith(DataLevelPrefixEnum.L2.getLevel()))
                .collect(Collectors.toList());
        //路径信息
        HtPathConfigurationDTO pathDTO = htPathConfigurationService.findById(taskDTO.getPathConfigId());
        //查找day天前满足数据等级的数据
        List<HtScanningMetadataDTO> beforeDayMetadataList = htScanningMetadataService
                .findBeforeDayAndLevelListData(day, metadataLevelList);
        List<DbDmsAlgorithmResultStoreDTO> beforeDayResultDataList = dbDmsAlgorithmResultStoreService
                .findBeforeDayAndLevelListData(day, resultDataLevelList);
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        //将查询出的数据源在近线表中查询，分别执行不同的策略
        if (!beforeDayMetadataList.isEmpty()) {
            logger.info("[数据分区-近线]{}天前的源数据共{}个",day,beforeDayMetadataList.size());
            Map<String,HtScanningMetadataDTO> beforeDayMetadataHash = beforeDayMetadataList
                    .stream().collect(Collectors.toMap(HtScanningMetadataDTO::getFileName,dto -> dto,(k1,k2) -> k2));
            List<String> fileNameList = new ArrayList<>(beforeDayMetadataHash.keySet());
            //近线表中已经存在的源数据信息
            List<DbDmsDatafileNearlineStorageDTO> nearlineExistMetadata = dbDmsDatafileNearlineStorageService
                    .findMetadataFileNameIn(fileNameList);
            List<String> nealineExistMetadataFileNameList = nearlineExistMetadata.stream()
                    .map(DbDmsDatafileNearlineStorageDTO::getFileName).collect(Collectors.toList());
            //近线表中不存在的源数据信息(当前FileNameList)
            fileNameList.removeAll(nealineExistMetadataFileNameList);
            //查询原来存储文件的路径HASH
            List<String> pathIdList = beforeDayMetadataList.stream()
                    .map(HtScanningMetadataDTO::getPathConfigId).distinct().collect(Collectors.toList());
            Map<String, HtPathConfigurationDTO> pathHash = htPathConfigurationService.findByIdList(pathIdList)
                    .stream().collect(Collectors.toMap(HtPathConfigurationDTO::getId, dto -> dto, (k1, k2) -> k2));
            //不存在的数据进行剪切、数据库迁移
            for (String fileName : fileNameList) {
                threadPool.execute(() -> {
                    HtScanningMetadataDTO metadataDTO = beforeDayMetadataHash.get(fileName);
                    HtPathConfigurationDTO srcPathDTO = pathHash.get(metadataDTO.getPathConfigId());
                    String prefixPath;
                    if (metadataDTO.getDataLevel().contains("L2")) {
                        prefixPath = srcPathDTO.getOutputPath();
                    } else {
                        prefixPath = srcPathDTO.getScanningPath();
                    }
                    File srcFile = new File(prefixPath + File.separator + metadataDTO.getFilePath());
                    File destFile = new File(pathDTO.getOutputPath() + File.separator + metadataDTO.getFilePath());
                    if (!destFile.exists() && srcFile.exists()) {
                        try {
                            //FileUtils.moveFileToDirectory(srcFile, destFile.getParentFile(), true);
                            FileUtil.moveFileToDirectorySupportsSendfile(srcFile, destFile.getParentFile());
                        } catch (IOException e) {
                            logger.error("[数据分区-近线]{}文件剪切异常:{}",srcFile.getAbsoluteFile(),e.getMessage());
                        }
                    }
                    DbDmsDatafileNearlineStorageDTO nearlineDTO = metadataToNearlineData(metadataDTO);
                    nearlineDTO.setPathConfigId(pathDTO.getId());
                    dbDmsDatafileNearlineStorageService.addEntity(nearlineDTO);
                    htScanningMetadataService.deleteOne(metadataDTO);
                });
            }
            //存在的数据进行删除原来的数据库信息和文件
            for (String fileName : nealineExistMetadataFileNameList) {
                threadPool.execute(() -> {
                    HtScanningMetadataDTO metadataDTO = beforeDayMetadataHash.get(fileName);
                    HtPathConfigurationDTO srcPathDTO = pathHash.get(metadataDTO.getPathConfigId());
                    String prefixPath;
                    if (metadataDTO.getDataLevel().contains("L2")) {
                        prefixPath = srcPathDTO.getOutputPath();
                    } else {
                        prefixPath = srcPathDTO.getScanningPath();
                    }
                    File srcFile = new File(prefixPath + File.separator + metadataDTO.getFilePath());
                    if (srcFile.exists()) {
                        boolean delete = srcFile.delete();
                        if (delete) {
                            logger.info("[数据分区-近线]{}文件删除成功",srcFile.getAbsoluteFile());
                        } else {
                            logger.info("[数据分区-近线]{}文件删除失败",srcFile.getAbsoluteFile());
                        }
                    }
                    htScanningMetadataService.deleteOne(metadataDTO);
                });
            }
        }
        if (!beforeDayResultDataList.isEmpty()) {
            logger.info("[数据分区-近线]{}天前的结果数据共{}个",day,beforeDayResultDataList.size());
            Map<String,DbDmsAlgorithmResultStoreDTO> beforeDayResultDataHash = beforeDayResultDataList
                    .stream().collect(Collectors.toMap(DbDmsAlgorithmResultStoreDTO::getFilename,dto -> dto,(k1,k2) -> k2));
            List<String> fileNameList = new ArrayList<>(beforeDayResultDataHash.keySet());
            //近线表中已经存在的结果数据信息
            List<DbDmsDatafileNearlineStorageDTO> nearlineExistResultData = dbDmsDatafileNearlineStorageService
                    .findResultDataFileNameIn(fileNameList);
            List<String> nealineExistResultDataFileNameList = nearlineExistResultData.stream()
                    .map(DbDmsDatafileNearlineStorageDTO::getFileName).collect(Collectors.toList());
            //近线表中不存在的结果数据信息(当前FileNameList)
            fileNameList.removeAll(nealineExistResultDataFileNameList);
            //查询原来存储文件的路径HASH
            List<String> pathIdList = beforeDayResultDataList.stream()
                    .map(DbDmsAlgorithmResultStoreDTO::getPathConfigId).distinct().collect(Collectors.toList());
            Map<String, HtPathConfigurationDTO> pathHash = htPathConfigurationService.findByIdList(pathIdList)
                    .stream().collect(Collectors.toMap(HtPathConfigurationDTO::getId, dto -> dto, (k1, k2) -> k2));
            //不存在的数据进行剪切、数据库迁移
            for (String fileName : fileNameList) {
                threadPool.execute(() -> {
                    DbDmsAlgorithmResultStoreDTO resultStoreDTO = beforeDayResultDataHash.get(fileName);
                    HtPathConfigurationDTO srcPathDTO = pathHash.get(resultStoreDTO.getPathConfigId());
                    File srcFile = new File(srcPathDTO.getOutputPath() + File.separator + resultStoreDTO.getFilepath());
                    File destFile = new File(pathDTO.getOutputPath() + File.separator + resultStoreDTO.getFilepath());
                    if (!destFile.exists() && srcFile.exists()) {
                        try {
                            //FileUtils.moveFileToDirectory(srcFile,destFile.getParentFile(),true);
                            FileUtil.moveFileToDirectorySupportsSendfile(srcFile, destFile.getParentFile());
                        } catch (IOException e) {
                            logger.error("[数据分区-近线]{}文件剪切异常:{}",srcFile.getAbsoluteFile(),e.getMessage());
                        }
                    }
                    DbDmsDatafileNearlineStorageDTO nearlineDTO = resultDataToNearlineData(resultStoreDTO);
                    nearlineDTO.setPathConfigId(pathDTO.getId());
                    dbDmsDatafileNearlineStorageService.addEntity(nearlineDTO);
                    dbDmsAlgorithmResultStoreService.deleteOne(resultStoreDTO);
                });
            }
            //存在的数据进行删除原来的数据库信息和文件
            for (String fileName : nealineExistResultDataFileNameList) {
                threadPool.execute(() -> {
                    DbDmsAlgorithmResultStoreDTO resultStoreDTO = beforeDayResultDataHash.get(fileName);
                    HtPathConfigurationDTO srcPathDTO = pathHash.get(resultStoreDTO.getPathConfigId());
                    File srcFile = new File(srcPathDTO.getOutputPath() + File.separator + resultStoreDTO.getFilepath());
                    if (srcFile.exists()) {
                        boolean delete = srcFile.delete();
                        if (delete) {
                            logger.info("[数据分区-近线]{}文件删除成功",srcFile.getAbsoluteFile());
                        } else {
                            logger.info("[数据分区-近线]{}文件删除失败",srcFile.getAbsoluteFile());
                        }
                    }
                    dbDmsAlgorithmResultStoreService.deleteOne(resultStoreDTO);
                });
            }
        }
        //查找day天内的满足数据等级的数据
        List<HtScanningMetadataDTO> afterDayMetadataList = htScanningMetadataService
                .findAfterDayAndLevelListData(day, metadataLevelList);
        List<DbDmsAlgorithmResultStoreDTO> afterDayResultDataList = dbDmsAlgorithmResultStoreService
                .findAfterDayAndLevelListData(day, resultDataLevelList);
        //将查询出的数据源在近线表中查询，分别执行不同的策略
        if (!afterDayMetadataList.isEmpty()) {
            logger.info("[数据分区-近线]{}天后的源数据共{}个",day,afterDayMetadataList.size());
            Map<String,HtScanningMetadataDTO> afterDayMetadataHash = afterDayMetadataList
                    .stream().collect(Collectors.toMap(HtScanningMetadataDTO::getFileName,dto -> dto,(k1,k2) -> k2));
            List<String> fileNameList = new ArrayList<>(afterDayMetadataHash.keySet());
            //近线表中已经存在的源数据信息
            List<DbDmsDatafileNearlineStorageDTO> nearlineExistMetadata = dbDmsDatafileNearlineStorageService
                    .findMetadataFileNameIn(fileNameList);
            List<String> nealineExistMetadataFileNameList = nearlineExistMetadata.stream()
                    .map(DbDmsDatafileNearlineStorageDTO::getFileName).collect(Collectors.toList());
            //近线表中不存在的源数据信息(当前FileNameList)
            fileNameList.removeAll(nealineExistMetadataFileNameList);
            //查询原来存储文件的路径HASH
            List<String> pathIdList = afterDayMetadataList.stream()
                    .map(HtScanningMetadataDTO::getPathConfigId).distinct().collect(Collectors.toList());
            Map<String, HtPathConfigurationDTO> pathHash = htPathConfigurationService.findByIdList(pathIdList)
                    .stream().collect(Collectors.toMap(HtPathConfigurationDTO::getId, dto -> dto, (k1, k2) -> k2));
            //不存在的数据进行剪切、数据库迁移
            for (String fileName : fileNameList) {
                threadPool.execute(() -> {
                    HtScanningMetadataDTO metadataDTO = afterDayMetadataHash.get(fileName);
                    HtPathConfigurationDTO srcPathDTO = pathHash.get(metadataDTO.getPathConfigId());
                    String prefixPath;
                    if (metadataDTO.getDataLevel().contains("L2")) {
                        prefixPath = srcPathDTO.getOutputPath();
                    } else {
                        prefixPath = srcPathDTO.getScanningPath();
                    }
                    File srcFile = new File(prefixPath + File.separator + metadataDTO.getFilePath());
                    File destFile = new File(pathDTO.getOutputPath() + File.separator + metadataDTO.getFilePath());
                    if (!destFile.exists() && srcFile.exists()) {
                        try {
                            //FileUtils.copyFile(srcFile,destFile);
                            FileUtil.copyFileSupportsSendfile(srcFile, destFile);
                        } catch (IOException e) {
                            logger.error("[数据分区-近线]{}文件复制异常:{}",srcFile.getAbsoluteFile(),e.getMessage());
                        }
                    }
                    DbDmsDatafileNearlineStorageDTO nearlineDTO = metadataToNearlineData(metadataDTO);
                    nearlineDTO.setPathConfigId(pathDTO.getId());
                    dbDmsDatafileNearlineStorageService.addEntity(nearlineDTO);
                });
            }
        }
        if (!afterDayResultDataList.isEmpty()) {
            logger.info("[数据分区-近线]{}天后的结果数据共{}个",day,afterDayResultDataList.size());
            Map<String,DbDmsAlgorithmResultStoreDTO> afterDayResultDataHash = afterDayResultDataList
                    .stream().collect(Collectors.toMap(DbDmsAlgorithmResultStoreDTO::getFilename,dto -> dto,(k1,k2) -> k2));
            List<String> fileNameList = new ArrayList<>(afterDayResultDataHash.keySet());
            //近线表中已经存在的结果数据信息
            List<DbDmsDatafileNearlineStorageDTO> nearlineExistResultData = dbDmsDatafileNearlineStorageService
                    .findResultDataFileNameIn(fileNameList);
            List<String> nealineExistResultDataFileNameList = nearlineExistResultData.stream()
                    .map(DbDmsDatafileNearlineStorageDTO::getFileName).collect(Collectors.toList());
            //近线表中不存在的结果数据信息(当前FileNameList)
            fileNameList.removeAll(nealineExistResultDataFileNameList);
            //查询原来存储文件的路径HASH
            List<String> pathIdList = afterDayResultDataList.stream()
                    .map(DbDmsAlgorithmResultStoreDTO::getPathConfigId).distinct().collect(Collectors.toList());
            Map<String, HtPathConfigurationDTO> pathHash = htPathConfigurationService.findByIdList(pathIdList)
                    .stream().collect(Collectors.toMap(HtPathConfigurationDTO::getId, dto -> dto, (k1, k2) -> k2));
            //不存在的数据进行剪切、数据库迁移
            for (String fileName : fileNameList) {
                threadPool.execute(() -> {
                    DbDmsAlgorithmResultStoreDTO resultStoreDTO = afterDayResultDataHash.get(fileName);
                    HtPathConfigurationDTO srcPathDTO = pathHash.get(resultStoreDTO.getPathConfigId());
                    File srcFile = new File(srcPathDTO.getOutputPath() + File.separator + resultStoreDTO.getFilepath());
                    File destFile = new File(pathDTO.getOutputPath() + File.separator + resultStoreDTO.getFilepath());
                    if (!destFile.exists() && srcFile.exists()) {
                        try {
                            //FileUtils.copyFile(srcFile,destFile);
                            FileUtil.copyFileSupportsSendfile(srcFile, destFile);
                        } catch (IOException e) {
                            logger.error("[数据分区-近线]{}文件复制异常:{}",srcFile.getAbsoluteFile(),e.getMessage());
                        }
                    }
                    DbDmsDatafileNearlineStorageDTO nearlineDTO = resultDataToNearlineData(resultStoreDTO);
                    nearlineDTO.setPathConfigId(pathDTO.getId());
                    dbDmsDatafileNearlineStorageService.addEntity(nearlineDTO);
                });
            }
        }
        threadPool.shutdown();
    }

    /**
     * 源数据对象转近线数据对象
     * @param metadataDTO
     * @return
     */
    private DbDmsDatafileNearlineStorageDTO metadataToNearlineData(HtScanningMetadataDTO metadataDTO) {
        DbDmsDatafileNearlineStorageDTO nearLineDTO = new DbDmsDatafileNearlineStorageDTO();
        nearLineDTO.setProductIdentify(metadataDTO.getProductIid());
        nearLineDTO.setSatellite(metadataDTO.getSatellite());
        nearLineDTO.setSensor(metadataDTO.getSensor());
        nearLineDTO.setResolution(metadataDTO.getResolution());
        nearLineDTO.setDataLevel(metadataDTO.getDataLevel());
        nearLineDTO.setRegion(metadataDTO.getRegion());
        nearLineDTO.setFilePath(metadataDTO.getFilePath());
        nearLineDTO.setFileDate(metadataDTO.getFileDate());
        nearLineDTO.setFileSize(metadataDTO.getFileSize());
        nearLineDTO.setFileName(metadataDTO.getFileName());
        nearLineDTO.setFileType(metadataDTO.getFileType());
        nearLineDTO.setCreateTime(metadataDTO.getCreateTime());
        nearLineDTO.setTaskPlanId(metadataDTO.getTaskPlanId());
        nearLineDTO.setSubPlanId(metadataDTO.getSubPlanId());
        nearLineDTO.setStation(metadataDTO.getStation());
        nearLineDTO.setObsMode(metadataDTO.getObsMode());
        nearLineDTO.setViewMode(metadataDTO.getViewMode());
        nearLineDTO.setOrbit(metadataDTO.getOrbitId());
        nearLineDTO.setProductMode(metadataDTO.getProductMode());
        nearLineDTO.setCoordinate(metadataDTO.getCoordinate());
        nearLineDTO.setComRatio(metadataDTO.getComRatio());
        nearLineDTO.setBands(metadataDTO.getBands());
        nearLineDTO.setTopLeftLat(metadataDTO.getTopleftLat());
        nearLineDTO.setTopLeftLon(metadataDTO.getTopleftLon());
        nearLineDTO.setTopRightLat(metadataDTO.getToprightLat());
        nearLineDTO.setTopRightLon(metadataDTO.getToprightLon());
        nearLineDTO.setBottomRightLat(metadataDTO.getBottomrightLat());
        nearLineDTO.setBottomRightLon(metadataDTO.getBottomrightLon());
        nearLineDTO.setBottomLeftLat(metadataDTO.getBottomleftLat());
        nearLineDTO.setBottomLeftLon(metadataDTO.getBottomleftLon());
        nearLineDTO.setLon(metadataDTO.getLon());
        nearLineDTO.setLat(metadataDTO.getLat());
        nearLineDTO.setViewNumber(metadataDTO.getViewNumber());
        nearLineDTO.setDataStatus(0);
        String polygon = new StringBuilder()
                .append("Polygon((")
                .append(metadataDTO.getTopleftLon()).append(" ").append(metadataDTO.getTopleftLat()).append(",")
                .append(metadataDTO.getBottomleftLon()).append(" ").append(metadataDTO.getBottomleftLat()).append(",")
                .append(metadataDTO.getBottomrightLon()).append(" ").append(metadataDTO.getBottomrightLat()).append(",")
                .append(metadataDTO.getToprightLon()).append(" ").append(metadataDTO.getToprightLat()).append(",")
                .append(metadataDTO.getTopleftLon()).append(" ").append(metadataDTO.getTopleftLat())
                .append("))").toString();
        WKTReader wktReader = new WKTReader();
        Geometry geometry;
        try {
            geometry = wktReader.read(polygon);
        } catch (ParseException e) {
            geometry = null;
        }
        nearLineDTO.setAddressLoc(geometry);
        return nearLineDTO;
    }

    /**
     * 结果数据对象转近线数据对象
     * @param resultDataDTO
     * @return
     */
    private DbDmsDatafileNearlineStorageDTO resultDataToNearlineData(DbDmsAlgorithmResultStoreDTO resultDataDTO) {
        DbDmsDatafileNearlineStorageDTO nearLineDTO = new DbDmsDatafileNearlineStorageDTO();
        nearLineDTO.setTaskRId(resultDataDTO.getTaskRId());
        nearLineDTO.setProductIdentify(resultDataDTO.getProductIdentify());
        nearLineDTO.setFileName(resultDataDTO.getFilename());
        nearLineDTO.setFilePath(resultDataDTO.getFilepath());
        nearLineDTO.setFileType(resultDataDTO.getFiletype());
        nearLineDTO.setFileDate(resultDataDTO.getFileDate());
        nearLineDTO.setFileSize(resultDataDTO.getFilesize());
        nearLineDTO.setDataLevel(resultDataDTO.getDataLevel());
        nearLineDTO.setSatellite(resultDataDTO.getSatellite());
        nearLineDTO.setSensor(resultDataDTO.getSensor());
        nearLineDTO.setResolution(resultDataDTO.getResolution());
        nearLineDTO.setRegion(resultDataDTO.getArea());
        nearLineDTO.setTaskPlanId(resultDataDTO.getTaskPlanId());
        nearLineDTO.setSubPlanId(resultDataDTO.getSubPlanId());
        nearLineDTO.setProduceTime(resultDataDTO.getProduceTime());
        nearLineDTO.setStartTime(resultDataDTO.getStartTime());
        nearLineDTO.setEndTime(resultDataDTO.getEndTime());
        nearLineDTO.setCreateTime(resultDataDTO.getCreatetime());
        nearLineDTO.setTopLeftLat(resultDataDTO.getTopLeftLat());
        nearLineDTO.setTopLeftLon(resultDataDTO.getTopLeftLon());
        nearLineDTO.setTopRightLat(resultDataDTO.getTopRightLat());
        nearLineDTO.setTopRightLon(resultDataDTO.getTopRightLon());
        nearLineDTO.setBottomRightLat(resultDataDTO.getBottomRightLat());
        nearLineDTO.setBottomRightLon(resultDataDTO.getBottomRightLon());
        nearLineDTO.setBottomLeftLat(resultDataDTO.getBottomLeftLat());
        nearLineDTO.setBottomLeftLon(resultDataDTO.getBottomLeftLon());
        nearLineDTO.setObsMode(resultDataDTO.getObsMode());
        nearLineDTO.setDataStatus(0);
        String polygon = new StringBuilder()
                .append("Polygon((")
                .append(resultDataDTO.getTopLeftLon()).append(" ").append(resultDataDTO.getTopLeftLat()).append(",")
                .append(resultDataDTO.getBottomLeftLon()).append(" ").append(resultDataDTO.getBottomLeftLat()).append(",")
                .append(resultDataDTO.getBottomRightLon()).append(" ").append(resultDataDTO.getBottomRightLat()).append(",")
                .append(resultDataDTO.getTopRightLon()).append(" ").append(resultDataDTO.getTopRightLat()).append(",")
                .append(resultDataDTO.getTopLeftLon()).append(" ").append(resultDataDTO.getTopLeftLat())
                .append("))").toString();
        WKTReader wktReader = new WKTReader();
        Geometry geometry;
        try {
            geometry = wktReader.read(polygon);
        } catch (ParseException e) {
            geometry = null;
        }
        nearLineDTO.setAddressLoc(geometry);
        return nearLineDTO;
    }

}
